package com.lwl.concurrency.synchr;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 一般情况下,thread1获取锁1,thread2获取锁2,紧着反转thread1获取锁2,thread2获取锁1
 * 很容易产生死锁,但是使用了tryLock()后,线程不会一直等待获取锁,可以通过while循环重试
 * 只要多重试几次,线程总会得到需要的锁
 * @author liwenlong - 2018/3/27 17:36
 */
public class TryLockTest2 implements Runnable {

    public static ReentrantLock lock1 = new ReentrantLock();
    public static ReentrantLock lock2 = new ReentrantLock();

    int lock;

    public TryLockTest2(int lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        if (lock == 1) {
            while (true) {
                if (lock1.tryLock()) {
                    try {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (lock2.tryLock()) {
                            System.out.println(Thread.currentThread().getName() + ":My Job done");
                            lock2.unlock();
                            return;
                        }
                    } finally {
                        lock1.unlock();
                    }
                }
            }
        }else{
            while (true){
                if (lock2.tryLock()){
                    try{
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (lock1.tryLock()){
                            System.out.println(Thread.currentThread().getName()+":My Job done");
                            lock1.unlock();
                            return;
                        }
                    }finally {
                        lock2.unlock();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        TryLockTest2 tryLockTest1 = new TryLockTest2(1);
        TryLockTest2 tryLockTest2 = new TryLockTest2(2);

        new Thread(tryLockTest1).start();
        new Thread(tryLockTest2).start();

    }


}
